
package ChatController;

import ChatGUI.ChatGUI;
import ChatNI.ChatNI;
import common.*;
import java.net.*;
import java.util.HashMap;
import java.util.logging.*;

/**
 *
 * @author Marion et Nicolas
 */

/**Le ChatController contrôle les changements d'états de la classe Model (Observable) pour les transmettre à la classe 
 ChatGUI (Observer) qui peut alors se mettre à jour**/

public class ChatController {
    private ChatNI reseau;
    private Model modele;
    
    
    private String localUser;
    private HashMap listUsers;
    private String logInController;

    private Hello hello;
    private Bye bye;
    private Text text;
    
 /**
     * Constructeur du ChatController : création d'un réseau et d'un modèle associé
     * @param ni
     * @param mod 
     */
    
    public ChatController(ChatNI ni, Model mod){
        this.reseau = ni;
        this.modele=mod;
    }
    
     /**
  * Association du ChatController à une fenêtre ChatGUI 
  * @param gui 
  */

    
    /**
     * Méthode utilisée par le ChatNI lors d'une reconnexion (apres une deconnexion) 
     */
    public void sendReconnexion() {
        try {
            System.out.println("==> Alternative : On refabrique un paquet Hello...");
            hello=new Hello(logInController,InetAddress.getLocalHost(),true);
            reseau.sendViaUDP(hello,InetAddress.getByName("255.255.255.255"));
            System.out.println("==> Alternative : ...nouveau paquet Hello envoye avec succes");
        } catch (UnknownHostException ex) {
            Logger.getLogger(ChatController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
        
    
  /**
     * L'envoi depuis le ChatController dépend du type de message
     * Cette méthode est appelée par le ChatGUI
     * @param username
     * @param message 
     */
    public void sendToNI (String username, String message){
        try {
            text = new Text(InetAddress.getLocalHost(),message);
            InetAddress dest = (InetAddress)(modele.getAddrFromLogin(username));
            System.out.println(dest);
            reseau.sendViaUDP(text, dest);
            System.out.println("Je viens d'envoyer le message "+message+ " a "+username);
        } catch (Exception e) {
            System.out.println("Exception dans le sendToNI du ChatController");
        }
    }
  
      /**
     * Envoi d'un message en broadcast : les messages de type Hello ou Bye
     * @param login
     * @param message
     * @param ifHello
     * @param ifBye 
     */
    
    
    public void sendToAll (String login, String message, Boolean ifHello, Boolean ifBye){
            this.logInController = login;
            if (ifHello)  {
                try {
                    // Si premier booleen = True alors c'est un Hello !
                    hello=new Hello(login,InetAddress.getLocalHost(),true); // Pour notifier que je suis co !
                    reseau.sendViaUDP(hello,InetAddress.getByName("255.255.255.255"));                         // Pour notifier que je suis co !
                    modele.connected();
                } catch (UnknownHostException ex) {
                    Logger.getLogger(ChatController.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else if (ifBye) {
                System.out.println("je suis rentré ds la condition du ifBye");
                try {
                    bye=new Bye(InetAddress.getLocalHost());
                    reseau.sendViaUDP(bye,InetAddress.getByName("255.255.255.255")); 
                    modele.disconnected();
                } catch (UnknownHostException ex) {
                    Logger.getLogger(ChatController.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            else {
                try {
                    text = new Text(InetAddress.getLocalHost(),message);
                    reseau.sendViaUDP(text,InetAddress.getByName("255.255.255.255"));
                } catch (UnknownHostException ex) {
                    Logger.getLogger(ChatController.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

    }

    
    /**
     * Méthode appelée lorsqu'un utilisateur distant tente d'entrer en communication avec le localUser
     * @param username 
     */
    public void newConversation(String username){
        this.modele.userConversation(username);
    }    
    
        /**
     * Méthode appelée lors de la réception d'un message texte par le local user
     * @param addr
     * @param text 
     */
    
    public void textReceived(InetAddress addr, String text){
            String username = (String) modele.getLoginFromAddr(addr);
            System.out.println("le username dans le ChatController decode est : "+username);
            this.modele.userReception(username,text);
    }
        
    
    /**
     *Méthode appellée lors de la réception d'un message de type Hello 
     * Si le boolean est à "true", on répond
     * Dans le cas contraire, on ne répond pas
     * @param login
     * @param addr
     * @param rep 
     */
    
    public void newUser(String login, InetAddress addr, boolean rep){
        try {
            this.modele.userConnection(login,addr);
            
            if (rep){   // On envoie notre Hello false après l'avoir rajouté dans notre liste
                hello=new Hello(ChatGUI.logLocal,InetAddress.getLocalHost(),false);
                reseau.sendViaUDP(hello,InetAddress.getByName("255.255.255.255"));
            }
        } catch (UnknownHostException ex) {
            Logger.getLogger(ChatController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
        /**
     * Méthode appellée lors de la réception d'un message de type Bye 
     * Si le boolean est à "true", on répond
     * Dans le cas contraire, on ne répond pas
     * @param addr 
     */
    
    public void byeUser(InetAddress addr){
            String username = (String) modele.getLoginFromAddr(addr);
            System.out.println(username);
            this.modele.userDisconnection(username);
    }
}


        
  
 

